package com.example.backend.aspect;

import com.example.backend.exception.BusinessException;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * 性能监控切面
 * 自动记录方法执行时间和性能指标
 */
@Aspect
@Component
public class PerformanceMonitorAspect {
    
    private static final Logger log = LoggerFactory.getLogger(PerformanceMonitorAspect.class);
    
    // 慢查询阈值（毫秒）
    private static final long SLOW_QUERY_THRESHOLD = 1000;
    
    // 警告阈值（毫秒）
    private static final long WARNING_THRESHOLD = 500;
    
    /**
     * Controller层性能监控
     */
    @Pointcut("within(@org.springframework.web.bind.annotation.RestController *)")
    public void controllerMethods() {}
    
    /**
     * Service层性能监控
     */
    @Pointcut("within(@org.springframework.stereotype.Service *)")
    public void serviceMethods() {}
    
    /**
     * 监控Controller方法执行时间
     */
    @Around("controllerMethods()")
    public Object monitorControllerPerformance(ProceedingJoinPoint joinPoint) throws Throwable {
        return monitorMethodExecution(joinPoint, "CONTROLLER");
    }
    
    /**
     * 监控Service方法执行时间
     */
    @Around("serviceMethods()")
    public Object monitorServicePerformance(ProceedingJoinPoint joinPoint) throws Throwable {
        return monitorMethodExecution(joinPoint, "SERVICE");
    }
    
    /**
     * 通用方法执行监控
     */
    private Object monitorMethodExecution(ProceedingJoinPoint joinPoint, String layer) throws Throwable {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        String className = joinPoint.getTarget().getClass().getSimpleName();
        String methodName = method.getName();
        
        String executionId = String.format("%s-%s-%d", 
                layer, 
                methodName.toUpperCase(), 
                System.currentTimeMillis() % 10000);
        
        // 记录开始时间
        long startTime = System.currentTimeMillis();
        
        log.debug("⏱️  [{}] 开始执行: {}.{}", executionId, className, methodName);
        
        Object result = null;
        boolean hasError = false;
        Throwable caughtException = null;
        
        try {
            // 执行目标方法
            result = joinPoint.proceed();
            return result;
            
        } catch (Throwable throwable) {
            hasError = true;
            caughtException = throwable;
            throw throwable;
            
        } finally {
            // 计算执行时间
            long executionTime = System.currentTimeMillis() - startTime;
            
            // 根据执行时间决定日志级别
            if (hasError && caughtException != null) {
                // 区分业务异常和系统异常
                if (caughtException instanceof BusinessException) {
                    // 业务异常使用WARN级别，这是预期的业务逻辑
                    log.warn("⚠️ [{}] 业务异常: {}.{} - 消息: {} - 耗时: {}ms",
                            executionId, className, methodName, 
                            caughtException.getMessage(), executionTime);
                } else {
                    // 系统异常使用ERROR级别，记录完整堆栈
                    log.error("❌ [{}] 执行失败: {}.{} - 异常类型: {} - 消息: {} - 耗时: {}ms",
                            executionId, className, methodName, 
                            caughtException.getClass().getSimpleName(),
                            caughtException.getMessage(), executionTime, caughtException);
                }
                        
            } else if (executionTime >= SLOW_QUERY_THRESHOLD) {
                log.warn("🐌 [{}] 慢查询警告: {}.{} - 耗时: {}ms",
                        executionId, className, methodName, executionTime);
                        
            } else if (executionTime >= WARNING_THRESHOLD) {
                log.warn("⚠️  [{}] 性能警告: {}.{} - 耗时: {}ms",
                        executionId, className, methodName, executionTime);
                        
            } else {
                log.debug("✅ [{}] 执行完成: {}.{} - 耗时: {}ms",
                        executionId, className, methodName, executionTime);
            }
            
            // 记录性能指标（可以发送到监控系统）
            recordPerformanceMetrics(layer, className, methodName, executionTime, hasError);
        }
    }
    
    /**
     * 记录性能指标
     * 这里可以集成监控系统（如Prometheus、Micrometer等）
     */
    private void recordPerformanceMetrics(String layer, String className, String methodName, 
                                          long executionTime, boolean hasError) {
        // TODO: 集成监控系统
        // 例如：
        // meterRegistry.timer("method.execution.time",
        //     "layer", layer,
        //     "class", className,
        //     "method", methodName,
        //     "status", hasError ? "error" : "success"
        // ).record(executionTime, TimeUnit.MILLISECONDS);
        
        // 临时使用日志输出
        if (log.isTraceEnabled()) {
            log.trace("📊 性能指标: layer={}, class={}, method={}, time={}ms, error={}",
                    layer, className, methodName, executionTime, hasError);
        }
    }
}

